<template>
  <div>
    <!-- 新增按钮 -->
    <el-button
      type="primary"
      size="small"
      icon="el-icon-plus"
      @click="showDialog = true"
      >新增角色</el-button
    >
    <!-- 表格 -->
    <!-- data：绑定表格要显示的数据，绑定的是数组类型，数组中每个元素是对象 -->
    <!-- 数组有多少个元素，就有几行 -->
    <el-table :data="tableData" style="width: 100%">
      <!-- 有几列就写几个el-table-column -->
      <!-- 使用prop来指定绑定要显示的属性 -->
      <!-- label设置表头这一列的文字 -->
      <el-table-column type="index" label="序号" />
      <el-table-column prop="name" label="角色名" />
      <el-table-column prop="description" label="描述" />

      <!-- 默认情况下 el-table-column只能显示文字，通过prop属性绑定文字  -->
      <!-- 如果没法满足需求就用插槽自定义 -->
      <el-table-column label="操作">
        <!-- scope是一个对象，可以解构出里面的属性，比如说解构出row -->
        <template slot-scope="{ row }">
          <!-- scope.row里面包含这一行的数据 -->
          <!-- <span>{{ scope.row }}</span> -->
          <el-link @click="assignPermission(row.id)" type="primary">分配权限</el-link>
          <el-link style="margin: 0 10px" type="primary" @click="doEdit(row.id)"
            >修改</el-link
          >
          <el-link type="primary" @click="doDel(row.id)">删除</el-link>
        </template>
      </el-table-column>
    </el-table>
    <!-- 分页 -->
    <!--
        :page-sizes对应一个数组，数组可以指定可以选择的页容量（具体去看官网）
            例 :page-sizes="[100, 200, 300, 400]"

        @size-change：当页容量发生改变触发，参数是改变后的页容量值

        @current-change：页码改变事件（用的上），参数是改变后的页码

        :current-page="page"：设置当前页码值
            加一个sync代表它内部可以改变page变量的值,不加改变不了

        :page-size 设置当前的页容量（一页显示多少条）

        :total 设置数据总量

        layout用来设置分页里各元素里的排列
            sizes： 如果有它代表有页容量的选择
            total： 如果有它代表有总页数的显示
            prev：  如果有它代表有上一页
            pager： 代表有全部页码
            next：  代表有下一页按钮
            它的顺序是从左往右依次排列
     -->
    <el-pagination
      style="text-align: center"
      :current-page.sync="pageInfo.page"
      :page-size="pageInfo.pagesize"
      :total="pageInfo.total"
      layout="total, prev, pager, next"
      @current-change="handleCurrentChange"
    />

    <add-role ref="addRole" :show-dialog.sync="showDialog" @reload="reload" />

    <!-- 放一个对话框做分配权限 -->
    <el-dialog @close="close" title="分配权限" :visible.sync="showPerDialog">
      <el-tree ref="tree" node-key="id" :default-checked-keys="chkList" check-strictly :data="treeData" default-expand-all :props="props" show-checkbox=""> </el-tree>

      <div style="text-align:center">
        <el-button @click="close">取消</el-button>
        <el-button @click="saveRole" type="primary">确定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { roleList, deleteRole, roleDetail, updateRole } from '@/api/roles'
import { getPermissionList } from '@/api/permission'
import { arrayToTree } from '@/utils'
// 导入组件
import AddRole from './AddRole.vue'
export default {
  components: {
    AddRole
  },
  data() {
    return {
      treeData: [],
      // 保存当前被点的角色信息
      currentRole: {},
      // 设置默认选中
      chkList: [],
      props: {
        // 指定要显示文字对应哪个属性
        label: 'name'
      },
      showPerDialog: false,
      showDialog: false,
      pageInfo: {
        page: 1,
        pagesize: 10,
        total: 0
      },
      tableData: [
        {
          date: '2016-05-02',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1518 弄'
        },
        {
          date: '2016-05-04',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1517 弄'
        },
        {
          date: '2016-05-01',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1519 弄'
        },
        {
          date: '2016-05-03',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1516 弄'
        }
      ]
    }
  },

  created() {
    // 加载数据
    this.loadData()
  },
  methods: {
    // 保存权限
    async saveRole () {

      // 拿到被选中的权限id，并赋值给当前角色的permIds
      this.currentRole.permIds = this.$refs.tree.getCheckedKeys()
      // 调用接口做分配权限
      const res = await updateRole(this.currentRole)
      this.$message.success(res.message)
      this.close()
    },
    close () {
      // 清空选中
      this.chkList = []
      this.showPerDialog = false
    },
    async assignPermission (id) {

      // 加载出最新的权限列表
      const res = await getPermissionList()
      // 把转成树形的权限数据赋值给tre
      this.treeData = arrayToTree(res.data, '0')

      // 根据id获取到当前这个角色所拥有的权限
      const res2 = await roleDetail(id)
      // 保存起来
      this.currentRole = res2.data
      this.chkList = res2.data.permIds

      // 显示出对话框
      this.showPerDialog = true
    },
    async doEdit(id) {
      // 根据id需要加载出数据，显示到对话框
      await this.$refs.addRole.getDetail(id)
      // 等上面查出数据后才显示出来
      this.showDialog = true
    },
    // 重新加载数据
    reload(isAdd) {
      // 只有新增才需要加载最后一页
      if (isAdd) {
        // 这个被调用意味着添加成功，要刷新最后一页
        // 我要把页码改成最后一页
        // 添加成功意味着总数量+1
        this.pageInfo.total++
        // 再用最新的总数量除以页容量算出最新的页码数
        // 总页数 = Math.ceil( 总数量 / 页容量 )
        this.pageInfo.page = Math.ceil(
          this.pageInfo.total / this.pageInfo.pagesize
        )
      }

      this.loadData()
    },
    // 加载数据
    async loadData() {
      const res = await roleList(this.pageInfo)
      // 把得到的数据绑定给table绑定的tableData
      this.tableData = res.data.rows
      this.pageInfo.total = res.data.total
    },
    // 页码点击事件
    handleCurrentChange() {
      // 要根据最新的页码发请求
      // 为什么直接调用发请求就行了？
      // 因为它内部传入的是this.pageInfo
      // this.pageInfo.page 是通过 .sync 绑定的
      // 那就意味着页码改变时，this.pageInfo.page 的值改变了
      // 所以直接调用即可
      this.loadData()
    },

    // 删除角色的点击事件
    doDel(id) {
      // 删除之前最好问一下是否确认要删除
      this.$confirm('确认是否要删除', '是否删除')
        .then(async() => {
          const res = await deleteRole(id)
          // 弹出提示
          this.$message.success(res.message)

          // 判断当前是不是最后一页，并且是否只有最后一条
          // 本质上只有一个条件： 判断当前页数据是否只有一条
          // 因为只有最后一页才可能只有一条数据
          // 并且它不是第一页
          if (this.tableData.length == 1 && this.pageInfo.page != 1) {
            // 那就让页码-1（也就是刷新上一页）
            // 例如当前是第三页只有最后一条，删完就应该刷新第二页
            this.pageInfo.page--
          }

          // 重新加载数据
          this.loadData()
        })
        .catch(() => {})
    }
  }
}
</script>

<style>
</style>
